在上一篇成功實作最基本的WebFlux功能,看到了一些有點熟悉又有點陌生的新朋友,在這邊補充說明。
Spring 同樣保留了支援annotation-based,依然可以使用熟悉的Spring MVC各式annotation(@RequestMapping、@RestController...),那為什麼需要有Handler&Router?
首先如果你對原本的annotation感到十分親切,當然可以繼續採用原本的寫法,一樣直覺好用,但畢竟Reactive我們希望能夠Functional,所以如果是一個新的專案想要嘗試Reactive Spring,那擁抱Functional的Handler&Router是一個不錯的選擇。
ServerResponse類似以前的ResponseEntity,含有status、header、body,提供了更多方法更加的Functional。ServerRequest 在原有的Spring MVC當中並沒有這樣的角色,Spring透過各式annotation(@RequestMapping、@Valid)自動幫你帶入指定的Object,雖然非常方便,但其實如果你沒有深入去了解,是沒辦法從程式碼去連結到行為與資料(都是背後處理掉),而且不容易繼承來進行客製化,annotation如果要取得路徑或是其他資料需要透過反射(reflection),相對就會有效能與type erasure的問題,ServerRequest與ServerResponse 改為Functional的風格則會讓過程更佳清楚。
public class PersonHandler {
private final PersonRepository repository;
public PersonHandler(PersonRepository repository) {
this.repository = repository;
}
public Mono<ServerResponse> listPeople(ServerRequest request) {
Flux<Person> people = repository.allPeople();
return ok().contentType(APPLICATION_JSON).body(people, Person.class);
}
public Mono<ServerResponse> createPerson(ServerRequest request) {
Mono<Person> person = request.bodyToMono(Person.class);
return ok().build(repository.savePerson(person));
}
public Mono<ServerResponse> getPerson(ServerRequest request) {
int personId = Integer.valueOf(request.pathVariable("id"));
return repository.getPerson(personId)
.flatMap(person -> ok().contentType(APPLICATION_JSON).bodyValue(person))
.switchIfEmpty(ServerResponse.notFound().build());
}
}
類似於RestTemplate,是一個functional的Api,支援non-blocking/blocking、streaming,寫起來更加的流暢。透過Codecs來處理(serializing /deserializing )我們需要使用的物件,Codecs 同樣類似於Spring MVC的HttpMessageConverter。
WebClient webClient = WebClient.builder()
.codecs(configurer -> {
CustomDecoder decoder = new CustomDecoder();
configurer.customCodecs().registerWithDefaultConfig(decoder);
})
.build();
透過ntellij動demo專案時發生一個錯誤,推測可能是啟動JMX(管理JVM的內的entity,視覺化的呈現)時pringApplication未開啟完成導致
javax.management.InstanceNotFoundException: org.springframework.boot:type=Admin,name=SpringApplication
參考stackoverflow回答則可正常執行https://stackoverflow.com/questions/50436108/javax-management-instancenotfoundexception-org-springframework-boottype-admin
接下來會稍微深入一點來看Handler&Router。
開始到了文章越來越難產的一個階段,最後八篇!